package com.e3.core.utils;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;


public class FileUtils {
	/**
	 * get the jar file contain a class
	 * @param clazz
	 * @return
	 */
	public static URL getJarUrlOfClass(Class<?> clazz){
		return clazz.getProtectionDomain().getCodeSource().getLocation();
	}
	/**
	 * get all files whose name start with a prefix before '*' char from a jar file.
	 * @param fileName
	 * @return
	 */
	public static List<File> getFilesFromJarWithStar(String fileName){
		return getFilesFromJarWithStar(FileUtils.class,fileName);
	}
	/**
	 * get all files whose name start with a prefix before '*' char from a jar file contain the given class.
	 * @param clazz
	 * @param fileName
	 * @return
	 */
	public static List<File> getFilesFromJarWithStar(Class<?> clazz,String fileName){
		URL url = getJarUrlOfClass(clazz);
		return getFilesFromJarWithStar(new File(url.getFile()),fileName);
	}
	/**
	 * get all files whose name start with a prefix before '*' char from a given jar file.
	 * @param jarFile
	 * @param fileName
	 * @return
	 */
	public static List<File> getFilesFromJarWithStar(File jarFile,String fileName){
		List<File> files = new ArrayList<File>();
		if(jarFile == null||jarFile.isDirectory()){
			return files;
		}
		String s[] = getFileNameAndType(fileName); 
		String fName = s[0];
		String fType = s[1];
		try {
			JarFile zipFile = new JarFile(jarFile);
			
			Enumeration<JarEntry> jarEntrys = zipFile.entries();
			for (; jarEntrys.hasMoreElements();) {
				JarEntry jarEntry = jarEntrys.nextElement();			
				if(jarEntry.isDirectory()){
					System.out.println(jarEntry.toString());
					continue;
				}
				String name = jarEntry.getName();
				int index = name.lastIndexOf("/");
				String noPathName = name;
				if(index>0){
					noPathName = name.substring(index+1);
				}
		        if(noPathName.startsWith(fName)){
		        	if(fType==null){
			        	URL url = Thread.currentThread().getContextClassLoader().getResource(name);
			        	files.add(new File(url.getFile()));
		        	}
		        	else if(name.endsWith(fType)){
			        	URL url = Thread.currentThread().getContextClassLoader().getResource(name);
			        	files.add(new File(url.getFile()));
		        	}
		        	
		        }
			}
		} catch (Exception e) {
		}
		java.util.Collections.sort(files);
		return files;
		
	}
	/**
	 * get the current class path.
	 * @return
	 */
	public static List<File> getCurrentClassPath(){
		List<File> files = new ArrayList<File>();
		String cp = System.getProperty("java.class.path");
		String[] cps = cp.split(";");
		for (String string : cps) {
			files.add(new File(string));
		}
		return files;
	}
	/**
	 * get all files whose name start with a prefix before '*' char from a path.
	 * @param parentPath
	 * @param fileName
	 * @return
	 */
	public static List<File> getFileFromPathWithStar(File parentPath,String fileName){
		String s[] = getFileNameAndType(fileName); 
		String fName = s[0];
		String fType = s[1];
		
		return getFileFromPathWithStar(parentPath,fName,fType);
	}
	
	private static List<File> getFileFromPathWithStar(File parentPath,String fileName,String fileType){
		List<File> files = new ArrayList<File>();
		if(parentPath==null||parentPath.isFile()){
			return files;
		}
		
		File[] allFiles = parentPath.listFiles();
		for (File file : allFiles) {
			String fName = file.getName();
			System.out.println(fName);
			if(file.isFile()&&fName.startsWith(fileName)&&fName.endsWith(fileType)){
				files.add(file);
			}
			else if(file.isDirectory()){
				List<File> fs = getFileFromPathWithStar(file,fileName,fileType);
				for (File file2 : fs) {
					files.add(file2);
				}
			}
		}
		return files;
	}
	/**
	 * get all files whose name start with a prefix before '*' char from the current class path.
	 * @param fileName
	 * @return
	 */
	public static List<File> getFileFromClassPathWithStar(String fileName){
		List<File> targetFiles = new ArrayList<File>();
		
		List<File> files = getCurrentClassPath();
		for (File file : files) {
			if(file.isDirectory()){
				List<File> fs = getFileFromPathWithStar(file, fileName);
				for (File file2 : fs) {
					targetFiles.add(file2);
				}
			}
			else if(file.isFile()){
				String name = file.getName();
				if(name.endsWith(".jar")||name.endsWith(".zip")){
					List<File> fs = getFilesFromJarWithStar(fileName);
					for (File file2 : fs) {
						targetFiles.add(file2);
					}
				}
			}
		}
		return targetFiles;
	}
	/**
	 * 
	 * @param clazz
	 * @param fileName
	 * @return
	 */
	public static List<File> getFileFromCurrentProjectWithStar(Class<?> clazz,String fileName){
		List<File> targetFiles = new ArrayList<File>();
		
		List<File> files = getCurrentClassPath();
		for (File file : files) {
			if(file.isDirectory()){
				List<File> fs = getFileFromPathWithStar(file, fileName);
				for (File file2 : fs) {
					targetFiles.add(file2);
				}
			}
		}
		List<File> fs = getFilesFromJarWithStar(clazz, fileName);
		for (File file : fs) {
			targetFiles.add(file);
		}
		return targetFiles;
	}
	/**
	 * 
	 * @param fileName
	 * @return
	 */
	private static String[] getFileNameAndType(String fileName){
		String[] fileS = new String[2];
		if(fileName==null){
			return fileS;
		}
		String fName = fileName;
		String fType = null;
		int index = fName.lastIndexOf(".");
		if(index>0){
			fType = fName.substring(index+1);
		}
		index = fName.indexOf("*");
		if(index>0){
			fName = fName.substring(0,index);
		}
		
		fileS[0] = fName;
		fileS[1] = fType;
		return fileS;
	}
	
	public static void main(String[] args){
//		FileUtils.getFilesFromJarWithStar(Log.class,"NOTICE");
		//System.out.println(System.getProperty("java.class.path"));
		getCurrentClassPath();
	}
	
}
